home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
...taking it to the Macs!
/
...taking it to the Macs!.iso
/
Extras
/
ActiveX Mac SDK
/
ActiveX SDK
/
Container Common
/
CActiveXScheduler.cpp
< prev
next >
Wrap
Text File
|
1997-01-03
|
12KB
|
434 lines
// ===========================================================================
// CActiveXScheduler.cpp ©1996 Microsoft Corporation. All rights reserved.
// ===========================================================================
//
// schedules Active X idle tasks
#ifdef PowerPlant_PCH
#include PowerPlant_PCH
#endif
#include "CActiveXScheduler.h"
CActiveXScheduler* CActiveXScheduler::sActiveXScheduler = NULL;
static Int16 CompareSchedControlStruct(SchedControlStruct *p1, SchedControlStruct *p2);
#pragma mark === CActiveXScheduler Constructor & Destructor ===
// ---------------------------------------------------------------------------
// • CActiveXScheduler::GetActiveXScheduler [static]
// ---------------------------------------------------------------------------
// creates a single instance
CActiveXScheduler*
CActiveXScheduler::GetActiveXScheduler(Boolean8 MakeIt)
{
if (!sActiveXScheduler && MakeIt)
sActiveXScheduler = new CActiveXScheduler;
return sActiveXScheduler;
}
// ---------------------------------------------------------------------------
// • CActiveXScheduler::CActiveXScheduler
// ---------------------------------------------------------------------------
// default constructor
CActiveXScheduler::CActiveXScheduler()
{
mScheduledControls = NULL;
mNeedsSorting = false;
}
// ---------------------------------------------------------------------------
// • CActiveXScheduler::~CActiveXScheduler
// ---------------------------------------------------------------------------
// destructor
CActiveXScheduler::~CActiveXScheduler(void)
{
if (mScheduledControls)
::DisposeHandle(Handle(mScheduledControls));
}
#pragma mark === CActiveXScheduler Idle methods ===
// ---------------------------------------------------------------------------
// • CActiveXScheduler::Idle
// ---------------------------------------------------------------------------
// give time to scheduled active x objects
ErrorCode
CActiveXScheduler::Idle(Boolean8 inNullEvent)
{
if (mScheduledControls)
{
if (mNeedsSorting)
Sort();
// give time to controls
::HLockHi(Handle(mScheduledControls));
SchedControlStruct* here = *mScheduledControls;
SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + ::GetHandleSize(Handle(mScheduledControls)));
Int32 CurrentTime = ::TickCount();
while (here < end && here->WaitUntil <= CurrentTime)
{
if (here->AfterAllEvents || inNullEvent)
{
here->Control->DoIdle(here->ControlRefCon);
// reschedule the control if its waituntil time changes
if (here->Interval > 0)
{
mNeedsSorting = true;
here->WaitUntil = CurrentTime + here->Interval;
}
}
here++;
}
::HUnlock(Handle(mScheduledControls));
}
return S_OK;
}
// ---------------------------------------------------------------------------
// • CActiveXScheduler::IdleControl
// ---------------------------------------------------------------------------
// give time to the one control if it is registered to want it
ErrorCode
CActiveXScheduler::IdleControl(Boolean8 inNullEvent, IControl* inControl)
{
if (mScheduledControls)
{
if (mNeedsSorting)
Sort();
// give time to the control
::HLockHi(Handle(mScheduledControls));
SchedControlStruct* here = *mScheduledControls;
SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + ::GetHandleSize(Handle(mScheduledControls)));
Int32 CurrentTime = ::TickCount();
while (here < end && here->WaitUntil <= CurrentTime)
{
if ((here->AfterAllEvents || inNullEvent) && here->Control == inControl)
{
here->Control->DoIdle(here->ControlRefCon);
// reschedule the control if its waituntil time changes
if (here->Interval > 0)
{
mNeedsSorting = true;
here->WaitUntil = CurrentTime + here->Interval;
}
}
here++;
}
::HUnlock(Handle(mScheduledControls));
}
return S_OK;
}
#pragma mark === CActiveXScheduler change queue items ===
// ---------------------------------------------------------------------------
// • CActiveXScheduler::ScheduleControl
// ---------------------------------------------------------------------------
// schedule a control - adding it if it isn't there, changing its time if it is
ErrorCode
CActiveXScheduler::ScheduleControl(Boolean8 AfterAllEvents, Int32 Interval, IControl* inControl, Uint32 ControlRefCon)
{
ErrorCode Result = E_FAIL;
Uint32 WaitUntil = ::TickCount() + Interval;
Uint32 HandleBytes = 0;
AfterAllEvents = AfterAllEvents ? true : false; // be sure there are only two possible values
// first see if we can just overwrite an existing record
if (mScheduledControls)
{
HandleBytes = ::GetHandleSize(Handle(mScheduledControls));
// I'm not going to lock handles here since I make NO function calls
SchedControlStruct* here = *mScheduledControls;
SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + HandleBytes);
while (Result == E_FAIL && here < end)
{
if (here->Control == inControl && here->ControlRefCon == ControlRefCon)
{
mNeedsSorting = true;
Result = S_OK;
here->WaitUntil = WaitUntil;
here->Interval = Interval;
here->AfterAllEvents = AfterAllEvents;
}
else
here++;
}
}
if (Result == E_FAIL)
{
if (!mScheduledControls)
mScheduledControls = (SchedControlStruct**)::NewHandle(0);
if (mScheduledControls)
{
::SetHandleSize(Handle(mScheduledControls), HandleBytes + sizeof(SchedControlStruct));
if (::MemError() == noErr)
{
// again, no handle locking since there aren't any function calls
SchedControlStruct* here = (SchedControlStruct*)((Char8*)*mScheduledControls + HandleBytes);
mNeedsSorting = true;
here->Control = inControl;
here->ControlRefCon = ControlRefCon;
here->WaitUntil = WaitUntil;
here->Interval = Interval;
here->AfterAllEvents = AfterAllEvents;
Result = S_OK;
}
}
}
return Result;
}
// ---------------------------------------------------------------------------
// • CActiveXScheduler::RemoveControlByRefCon
// ---------------------------------------------------------------------------
// remove a specific control and refcon pair from the queue
ErrorCode
CActiveXScheduler::RemoveControlByRefCon(IControl* inControl, Uint32 ControlRefCon)
{
ErrorCode Result = E_FAIL;
if (mScheduledControls)
{
::HLock(Handle(mScheduledControls));
if (::MemError() == noErr)
{
Uint32 HandleBytes = ::GetHandleSize(Handle(mScheduledControls));
SchedControlStruct* here = *mScheduledControls;
SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + HandleBytes);
while (Result == E_FAIL && here < end)
{
if (here->Control == inControl && here->ControlRefCon == ControlRefCon)
{
Result = S_OK;
::BlockMove(here+1, here, (Char8*)end - (Char8*)(here+1));
HandleBytes -= sizeof(SchedControlStruct);
}
else
here++;
}
::HUnlock(Handle(mScheduledControls));
// if we removed something then resize the handle down
if (Result == S_OK)
::SetHandleSize(Handle(mScheduledControls), HandleBytes);
}
}
return Result;
}
// ---------------------------------------------------------------------------
// • CActiveXScheduler::RemoveControl
// ---------------------------------------------------------------------------
// remove all items in the queue belonging the the control
ErrorCode
CActiveXScheduler::RemoveControl(IControl* inControl)
{
ErrorCode Result = E_FAIL;
if (mScheduledControls)
{
::HLock(Handle(mScheduledControls));
if (::MemError() == noErr)
{
Uint32 HandleBytes = ::GetHandleSize(Handle(mScheduledControls));
SchedControlStruct* here = *mScheduledControls;
SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + HandleBytes);
while (here < end)
{
if (here->Control == inControl)
{
Result = S_OK;
::BlockMove(here+1, here, (Char8*)end - (Char8*)(here+1));
end--;
}
else
here++;
}
// if we removed something then resize the handle down
HandleBytes = (Char8*)end - (Char8*)*mScheduledControls;
::HUnlock(Handle(mScheduledControls));
if (Result == S_OK)
::SetHandleSize(Handle(mScheduledControls), HandleBytes);
}
}
return Result;
}
#pragma mark === CActiveXScheduler query scheduler methods ===
// ---------------------------------------------------------------------------
// • CActiveXScheduler::HasNullEventItems
// ---------------------------------------------------------------------------
// remove all items in the queue belonging the the control
Boolean8
CActiveXScheduler::HasNullEventItems(void)
{
Boolean8 Result = false;
if (mScheduledControls)
{
// I'm not going to lock handles here since I make NO function calls
SchedControlStruct* here = *mScheduledControls;
SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + ::GetHandleSize(Handle(mScheduledControls)));
while (!Result && here < end)
{
Result = !here->AfterAllEvents;
here++;
}
}
return Result;
}
// ---------------------------------------------------------------------------
// • CActiveXScheduler::HasAllEventItems
// ---------------------------------------------------------------------------
// remove all items in the queue belonging the the control
Boolean8
CActiveXScheduler::HasAllEventItems(void)
{
Boolean8 Result = false;
if (mScheduledControls)
{
Uint32 HandleBytes = ::GetHandleSize(Handle(mScheduledControls));
// I'm not going to lock handles here since I make NO function calls
SchedControlStruct* here = *mScheduledControls;
SchedControlStruct* end = (SchedControlStruct*)((Char8*)here + ::GetHandleSize(Handle(mScheduledControls)));
while (!Result && here < end)
{
Result = here->AfterAllEvents;
here++;
}
}
return Result;
}
#pragma mark === CActiveXScheduler private methods ===
// ---------------------------------------------------------------------------
// • CActiveXScheduler::Sort
// ---------------------------------------------------------------------------
// sort the job schedule queue - use a bubble sort since the queue shouldn't
// be very long nor very out of order
void
CActiveXScheduler::Sort(void)
{
Uint32 ItemCount;
if (mNeedsSorting && (!mScheduledControls ||
(ItemCount = ::GetHandleSize(Handle(mScheduledControls))/sizeof(SchedControlStruct)) <= 1))
mNeedsSorting = false;
if (mNeedsSorting)
{
SchedControlStruct *p1, *p2;
SchedControlStruct *begin = *mScheduledControls;
SchedControlStruct *end = begin + ItemCount - 1;
while (begin < end)
{
SchedControlStruct *newEnd = NULL;
for (p1 = begin, p2 = begin + 1; p2 <= end; p1++, p2++)
{
SchedControlStruct Temp;
if (CompareSchedControlStruct(p1, p2) > 0)
{
Temp = *p1;
*p1 = *p2;
*p2 = Temp;
newEnd = p1;
}
}
end = newEnd;
}
mNeedsSorting = false;
}
}
#pragma mark === static function ===
// ---------------------------------------------------------------------------
// • CompareSchedControlStruct
// ---------------------------------------------------------------------------
// comparison function - sort order is (WaitUntil ascending, NullOnly, Job, JobRefCon)
Int16 CompareSchedControlStruct(SchedControlStruct *p1, SchedControlStruct *p2)
{
Int32 ReturnValue = 1;
if (p1->WaitUntil < p2->WaitUntil)
ReturnValue = -1;
else if (p1->WaitUntil == p2->WaitUntil)
{
if (p1->AfterAllEvents && !p2->AfterAllEvents)
ReturnValue = -1;
else if (p1->AfterAllEvents == p2->AfterAllEvents)
{
if (p1->Control < p2->Control)
ReturnValue = -1;
else if (p1->Control == p2->Control)
{
if (p1->ControlRefCon < p2->ControlRefCon)
ReturnValue = -1;
else if (p1->ControlRefCon == p2->ControlRefCon)
ReturnValue = 0;
}
}
}
return ReturnValue;
}